package com.lsh.payment.service.cmpay;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lsh.payment.api.model.basevo.BaseResponse;
import com.lsh.payment.api.model.basevo.ExceptionStatus;
import com.lsh.payment.api.model.cmpay.CmActivateRequest;
import com.lsh.payment.api.model.cmpay.CmCheckInRequest;
import com.lsh.payment.api.model.cmpay.CmNotifyRequest;
import com.lsh.payment.api.service.cmpay.IcmRestService;
import com.lsh.payment.core.constant.RedisKeyConstant;
import com.lsh.payment.core.dao.redis.RedisStringDao;
import com.lsh.payment.core.exception.BusinessException;
import com.lsh.payment.core.model.config.PayConfig;
import com.lsh.payment.core.service.cmpay.IcmNotifyService;
import com.lsh.payment.core.service.config.ConfigService;
import com.lsh.payment.core.strategy.config.CmPayConfig;
import com.lsh.payment.core.util.pay.cm.CmSha256;
import com.lsh.payment.core.util.pay.cm.HttpCmProxy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;

/**
 * Project Name: lsh-payment
 *
 * @author miaozhuang
 * @date 16/11/7
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service(protocol = "rest", validation = "true")
@Path("cmpay")
public class CmRestServiceImpl implements IcmRestService {

    private final Logger logger = LoggerFactory.getLogger(CmRestServiceImpl.class);

    @Autowired
    private IcmNotifyService icmNotifyService;

    @Autowired
    private RedisStringDao redisStringDao;

    @Autowired
    private ConfigService configService;

    @Override
    @POST
    @Path("notify")
    @Produces({ContentType.TEXT_PLAIN_UTF_8})
    public String notify(@Context HttpServletRequest request) {

        String success;
        try {
            request.setCharacterEncoding("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try (BufferedReader reader = request.getReader()) {
            //参数-签名检查
            String authorization = request.getHeader("Authorization");
            logger.info("authorization {}", authorization);

            StringBuilder requestBody = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                requestBody.append(line);
            }
            logger.info("requestBody {}", requestBody);

            boolean flag = CmSha256.validateSign(requestBody.toString(), authorization, CmPayConfig.PUBLIC_KEY);

            logger.info("authorization diff builderAuthorization {}", flag);
            if (flag) {
                CmNotifyRequest cmNotifyRequest = JSON.parseObject(requestBody.toString(), CmNotifyRequest.class);
                this.icmNotifyService.cmNotify(cmNotifyRequest);
                success = "success";
            } else {
                logger.info("requestBody 签名校验失败 {}", requestBody);
                success = "fail";
            }
        } catch (BusinessException e) {
            success = "fail";
            logger.error("业务异常, code {}, message {}.", e.getCode(), e.getMessage());
        } catch (Exception e) {
            success = "fail";
            logger.error("服务端异常", e);
        }

        return success;
    }

    /**
     * 回调接口
     *
     * @param activateRequest 查询参数对象
     * @return BaseResponse    返回结果对象
     */
    @Override
    @POST
    @Path("activate")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({ContentType.APPLICATION_JSON_UTF_8})
    public BaseResponse activate(CmActivateRequest activateRequest) {

        BaseResponse baseResponse = new BaseResponse();

        try {
            HttpCmProxy httpCmProxy = new HttpCmProxy(CmPayConfig.PAY_BASE);

            String result = httpCmProxy.activate(activateRequest.getVendor_sn(), activateRequest.getVendor_key(), activateRequest.getAppid(), activateRequest.getCode());

            if (StringUtils.isBlank(result)) {
                baseResponse.setRet(9999);
                baseResponse.setMsg("终端激活失败");
                return baseResponse;
            }

            JSONObject terminal = JSON.parseObject(result);
            String terminal_sn = terminal.getString("terminal_sn");
            String terminal_key = terminal.getString("terminal_key");

            logger.info(" activate terminal info {}", JSON.toJSONString(terminal));
            if (StringUtils.isAnyBlank(terminal_sn, terminal_key)) {
                baseResponse.setRet(9988);
                baseResponse.setMsg("终端激活失败");
                return baseResponse;
            }

            redisStringDao.set(RedisKeyConstant.PAY_CM_SN, terminal_sn);
            redisStringDao.set(RedisKeyConstant.PAY_CM_KEY, terminal_key);

            PayConfig config = new PayConfig();
            config.setName("收钱吧秘钥");
            config.setContent(terminal.toJSONString());

            configService.updateConfig(config);

            baseResponse.setRet(0);
            baseResponse.setMsg(terminal.toJSONString());

        } catch (BusinessException e) {
            baseResponse.setRet(Integer.parseInt(e.getCode()));
            baseResponse.setMsg(e.getMessage());
            logger.error("业务异常, code {}, message {}.", e.getCode(), e.getMessage());
        } catch (Exception e) {
            baseResponse.setRet(Integer.parseInt(ExceptionStatus.E3001001.getCode()));
            baseResponse.setMsg(ExceptionStatus.E3001001.getMessage());
            logger.error("服务端异常", e);
        }

        return baseResponse;
    }

    /**
     * 签到接口
     *
     * @param checkInRequest 查询参数对象
     * @return BaseResponse    返回结果对象
     */

    @Path("checkin")
    @POST
    @Override
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({ContentType.APPLICATION_JSON_UTF_8})
    public BaseResponse checkin(CmCheckInRequest checkInRequest) {
        BaseResponse baseResponse = new BaseResponse();

        try {
            HttpCmProxy httpCmProxy = new HttpCmProxy(CmPayConfig.PAY_BASE);

            checkInRequest.setTerminal_sn(redisStringDao.get(RedisKeyConstant.PAY_CM_SN));
            checkInRequest.setTerminal_key(redisStringDao.get(RedisKeyConstant.PAY_CM_KEY));

            String result = httpCmProxy.checkin(checkInRequest.getTerminal_sn(), checkInRequest.getTerminal_key());

            if (StringUtils.isBlank(result)) {
                baseResponse.setRet(9999);
                baseResponse.setMsg("终端签到失败");
                return baseResponse;
            }

            JSONObject terminal = JSON.parseObject(result);
            String terminal_sn = terminal.getString("terminal_sn");
            String terminal_key = terminal.getString("terminal_key");
            logger.info(" activate checkin info {}", JSON.toJSONString(terminal));
            if (StringUtils.isAnyBlank(terminal_sn, terminal_key)) {
                baseResponse.setRet(9988);
                baseResponse.setMsg("终端签到失败");
                return baseResponse;
            }

            redisStringDao.set(RedisKeyConstant.PAY_CM_SN, terminal_sn);
            redisStringDao.set(RedisKeyConstant.PAY_CM_KEY, terminal_key);

            PayConfig config = new PayConfig();
            config.setName("收钱吧秘钥");
            config.setContent(terminal.toJSONString());

            configService.updateConfig(config);

            baseResponse.setRet(0);
            baseResponse.setMsg(terminal.toJSONString());

        } catch (BusinessException e) {
            baseResponse.setRet(Integer.parseInt(e.getCode()));
            baseResponse.setMsg(e.getMessage());
            logger.error("业务异常, code {}, message {}.", e.getCode(), e.getMessage());
        } catch (Exception e) {
            baseResponse.setRet(Integer.parseInt(ExceptionStatus.E3001001.getCode()));
            baseResponse.setMsg(ExceptionStatus.E3001001.getMessage());
            logger.error("服务端异常", e);
        }

        return baseResponse;
    }


}
